-------------------------------------------------------------------------------------
-- -*- coding: utf-8 -*-
--
-- @author:   zxf
-- @email:    07291@qq.com
-- @date:     2024/7/9
-- @module:   bt
-- @describe: 行为框架
-- @version:  v1.0
--

-------------------------------------------------------------------------------------

---@class bt
local bt = {}
local this = bt

---@type behavior_node
local behavior_node = import('bt/bt_plugin/behavior3/behavior_node')
---@type load_tree
local load_tree = import('bt/bt_framework/func/load_tree')
---@type owner_base
local owner_base = import('bt/bt_framework/owner_base')
---@type treeArr_base
local treeArr_base = import('bt/bt_framework/treeArr_base')
---@type state_tree
local state_tree = import('bt/bt_framework/state/state_tree')

local ctx = {
    time = 0,
    lastDeltaTime = nil,
    deltaTime = nil,
    realDeltaTime = nil,
    setDeltaTime = function(t, deltaTime)
        if deltaTime then
            t.deltaTime = deltaTime
        end
    end
}

this.owner = owner_base:new()
-- 决策树
this.strategic_tree = treeArr_base:new()
-- 附属树
this.subsidiary_tree = treeArr_base:new()

-- 设置owner
function this.set_owner(owner)
    this.owner = owner
end

-- 设置决策树列表
function this.set_strategic_arr(data)
    this.strategic_tree:set_arr(data)
end

-- 设置行为树列表
function this.set_bt_arr(data)
    this.btTreeFileArr = data
end

-- 设置附属树列表
function this.set_subsidiary_tree(data)
    this.subsidiary_tree:set_arr(data)
end

-- 加载树
-- @param rootPath 根路径
function this.load_tree(rootPath)
    load_tree.clear()
    -- 加载路径
    if rootPath then
        load_tree.set_rootPath(rootPath)
    end
    local owner = this.owner
    -- 设置节点路径
    behavior_node.process(import('node/process'))
    -- 配置只运行一次
    local configTree = load_tree.get_tree("初始配置", "config.json", ctx, owner)
    configTree:run()
    -- 决策树
    this.strategic_tree:init(ctx, this.owner)
    -- 目标完成处理
    local completeTree = load_tree.get_tree("on_main_target_complete.json", "on_main_target_complete.json", ctx, owner)
    -- 行为树初始化
    for _, v in ipairs(this.btTreeFileArr) do
        local tmpState = state_tree:new()
        local tmpTree = nil
        if v.filePath then
            tmpTree = load_tree.get_tree(v.filePath, v.filePath, ctx, owner)
        end
        local tmpCompleteTree = completeTree
        if v.completeFilePath then
            tmpCompleteTree = load_tree.get_tree(v.completeFilePath .. '完成处理', v.completeFilePath, ctx, owner)
        end
        tmpState:init(v.name, ctx, owner, tmpTree, tmpCompleteTree)
        owner:add_state(v.name, tmpState)
    end
    this.subsidiary_tree:init(ctx, owner)
    -- 初始化角色数据
    owner:init(ctx)
end

-- 运行树
-- @param defaultDeltaTime 默认时间间隔(毫秒)
function this.run_tree(defaultDeltaTime, realDeltaTime)
    local owner = this.owner
    ctx.realDeltaTime = realDeltaTime
    ctx.deltaTime = defaultDeltaTime
    -- 帧数递增
    ctx.time = ctx.time + 1
    local deltaTime = ctx.deltaTime
    -- 刷新角色数据
    owner:update_data(ctx)
    -- 决策和行为树运行
    this.bt_tree_update()
    -- 附属树运行
    this.subsidiary_tree_update()
    -- 行为树运行后刷新
    owner:last_update_data(ctx)
    -- 间隔时间限制
    deltaTime = this.deltaTime_limit(deltaTime)
    if (not ctx.lastDeltaTime and defaultDeltaTime ~= deltaTime) or ctx.lastDeltaTime and ctx.lastDeltaTime ~= deltaTime then
        --print(string.format('时间间隔改变为 %s', deltaTime))
    end
    ctx.lastDeltaTime = deltaTime
    return deltaTime
end

-- 行为树运行
function this.bt_tree_update()
    local owner = this.owner
    -- 决策树刷新
    if not owner:is_state_leaving() then
        this.strategic_tree:run()
    end
    owner:update_state()
end

-- 附属树运行
function this.subsidiary_tree_update()
    this.subsidiary_tree:run()
end

-- 间隔时间限制
function this.deltaTime_limit(deltaTime)
    if deltaTime ~= ctx.deltaTime then
        deltaTime = ctx.deltaTime
        if deltaTime <= 100 then
            deltaTime = 100
        end
        --print(string.format('修改延时间隔 %s', deltaTime))
    end
    return deltaTime
end

return this
